﻿using Assets.Core.Common.Web;
using Masuit.Tools;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NFine.Application.User;
using Nucleic.Core;
using Nucleic.Core.DoMain;
using Nucleic.Core.Utils;
using Nucleic.Core.Utils.hebcz;
using Nucleic.Web.Dto.BookInfo;
using Nucleic.Web.Models.Book;
using QRCoder;
using SqlSugar;
using System.Drawing;
using YinLong.Tool.Net.HttpHelperMin;
using Result = Assets.Core.Common.Web.Result;

namespace Nucleic.Web.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BookController : ControllerBase
    {
        private readonly ILogger<BookController> _logger;
        private IWebHostEnvironment _iHostEnvironment;
      
        public BookController(ILogger<BookController> logger, IWebHostEnvironment iHostEnvironment)
        {
            _logger = logger;
            _iHostEnvironment = iHostEnvironment;
            
        }
 
        /// <summary>
        /// 退款
        /// </summary>
        /// <param name="orders_id"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("Cancel")]
        public Result Cancel(string orders_id)
        {
            var book = SqlSugarFactory.Instance.Queryable<book_info>().First(i => i.orders_id == orders_id);
            if (book == null)
            {
                return (Result.fail("预约信息异常！"));
            }
            var order = SqlSugarFactory.Instance.Queryable<order_info>().First(i => i.orders_id == orders_id && i.status == "0");
            if (order == null)
            {
                return (Result.fail("订单信息异常！"));
            }
            var patient = SqlSugarFactory.Instance.Queryable<patient_info>().First(i => i.pat_id == book.pat_id);
            if (patient == null)
            {
                return (Result.fail("患者信息异常！"));
            }
            // 0=预约中,1=线上已缴费,2=社保卡已缴费,3=已采样(不能退费),4=退费,5=无法采集(1,5可以退款,5且非医保卡才可以退款)
            _logger.LogInformation($"退款单号[{orders_id}]->患者姓名{patient.name},开始处理");
            if (book.medicare == 1)
            {
                _logger.LogInformation($"退款单号[{orders_id}]->患者姓名{patient.name},医保卡支付请到现场退费");
                //医保卡的现场退费
                return (Result.fail("医保卡支付请到现场退费！"));
            }
            if ((book.status == "1" && book.medicare == 0) || (book.status == "5" && book.medicare == 0))
            {

                JHRefundApp jhRefundApp = new JHRefundApp();
                xmlToolApp XMLToolApp = new xmlToolApp();
                //查询建行本订单金额
                string returnStr = jhRefundApp.GetOrder(orders_id);
                _logger.LogInformation($"退款单号[{orders_id}]->患者姓名{patient.name},查询建行本订单:{returnStr}");
                //建行订单状态 成功000000
                var code = XMLToolApp.GetTextBydoc(returnStr, "RETURN_CODE");
                _logger.LogInformation($"退款单号[{orders_id}]->:患者姓名:" + patient.name + ",reutrncode:" + code);

                if (code == "000000")
                {

                    var pay = XMLToolApp.GetTextBydoc(returnStr, "PAYMENT_MONEY").ToDouble();
                    //已经退款金额
                    var refund = XMLToolApp.GetTextBydoc(returnStr, "REFUND_MONEY").ToDouble();
                    //退款备注
                    var msg = XMLToolApp.GetTextBydoc(returnStr, "RETURN_MSG");

                    //充值金额减去已经退款金额=现在在建行账上还剩余的金额
                    double krefund = pay - refund;

                    //建行端此笔款状态
                    var sate = XMLToolApp.GetTextBydoc(returnStr, "ORDER_STATUS");
                    //0:失败,1:成功,2:待银行确认,3:已部分退款,4:已全额退款,5:待银行确认
                    bool isReturnSucess = false;
                    if (sate == "1")
                    {
                        returnStr = jhRefundApp.Refund(krefund, orders_id);
                        _logger.LogInformation($"退款单号[{orders_id}]->患者姓名{patient.name},建行退款申请:{returnStr}");
                        code = XMLToolApp.GetTextBydoc(returnStr, "RETURN_CODE");
                        if (code == "000000")
                        {
                            isReturnSucess = true;
                        }
                    }
                    else if (sate == "4")
                    {
                        _logger.LogInformation($"退款单号[{orders_id}]->患者姓名{patient.name},建行已全额退款");

                        isReturnSucess = true;
                    }
                    if (isReturnSucess)
                    {
                        _logger.LogInformation($"退款单号[{orders_id}]->患者姓名{patient.name},退款成功处理数据库");
                        //可以退款
                        book.status = "4";
                        book.update_time = DateTime.Now;
                        SqlSugarFactory.Instance.Updateable(book).ExecuteCommand();

                        order.status = "1";
                        SqlSugarFactory.Instance.Updateable(order).ExecuteCommand();

                        order_info orderHc = new order_info()
                        {
                            pay_time = DateTime.Now,//退款时间
                            pat_id = order.pat_id,
                            appo_id = order.appo_id,
                            item_id = order.item_id,
                            price = -order.price,
                            num = order.num,
                            total_cost = order.total_cost,
                            orders_id = order.orders_id,
                            wx_order_no = order.wx_order_no,
                            status = "2",
                            tel = order.tel,
                            idnum = order.idnum,
                            pat_name = order.pat_name,
                            einvoicecode = order.einvoicecode,
                            einvoicenumber = order.einvoicenumber,
                            randomnumber = order.randomnumber,
                            invoiceStatus=order.invoiceStatus
                        };
                        SqlSugarFactory.Instance.Insertable(orderHc).ExecuteCommand();

                        //退发票
                        _logger.LogInformation($"退款单号[{orders_id}]->患者姓名{patient.name},查询发票状态");
                        var invStatus = hebczUtil.invoicestatus(orders_id);
                        _logger.LogInformation($"退款单号->[{orders_id}]->患者姓名:{order.pat_name}->查询发票状态:" + JsonConvert.SerializeObject(invStatus));
                        if (invStatus.code == 1 && invStatus.data.Count > 0)
                        {
                            //参考“4.2.1 开具医疗电子票据”业务请求，冲红票传入数据信息与原票必须
                            //保持一致，issuedate 开票日期（第 2 项）和 issuetime 开票时间（第 3 项）
                            //为当前时间
                            var item = SqlSugarFactory.Instance.Queryable<check_item>().First(i => i.item_id == order.item_id);
                            var set = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };

                            RedMedicaleInvoiceModel red = new RedMedicaleInvoiceModel()
                            {
                                einvoicespecimen = "1",
                                issuedate = DateTime.Now.ToString("yyyyMMdd"),
                                issuetime = DateTime.Now.ToString("hh:mm:ss"),
                                payerpartytype = "1",
                                payerpartyname = order.pat_name,
                                totalamount = double.Parse(order.price.ToString()).ToString(),
                                bizcode = orders_id,
                                handlingperson = hebczConst.handlingperson,
                                checker = hebczConst.checker,
                                fundpayamount = "0",
                                otherpayamount = "0",
                                accountpayamount = "0",
                                ownpayamount = double.Parse(order.price.ToString()).ToString(),
                                relatedinvoicecode = invStatus.data[0].einvoicecode,
                                relatedinvoicenumber = invStatus.data[0].einvoicenumber
                            };
                            red.details.Add(new details
                            {
                                itemcode = hebczConst.item_code,
                                itemname = hebczConst.item_name,
                                itemamount = double.Parse(order.price.ToString()).ToString(),

                            });
                            red.auxdetails.Add(new auxdetails
                            {
                                auxitemrelatedcode = hebczConst.item_code,
                                auxitemrelatedname = hebczConst.item_name,
                                auxitemname = item.name,
                                auxitemamount = double.Parse(order.price.ToString()).ToString()
                            });
                            _logger.LogInformation($"退款单号->[{orders_id}]->患者姓名:{order.pat_name}->红冲电子发票Data:" + JsonConvert.SerializeObject(red, set));
                            HttpHelperMin http = new HttpHelperMin();
                            HttpItemMin httpitem = new HttpItemMin()
                            {
                                URL = hebczConst.Url + "/mkoredmedicaleinvoice",
                                Method = "POST",
                                ContentType = "application/json",
                                Postdata = JsonConvert.SerializeObject(red),
                            };
                            var resule = http.GetHtml(httpitem);
                            _logger.LogInformation($"退款单号->[{orders_id}]->患者姓名:{order.pat_name}->红冲电子发票返回:" + resule.Html);
                            var d = JsonConvert.DeserializeObject<ReturnData<MeInvoiceStatusDto>>(resule.Html);
                            if (d!=null&&d.code == 1)
                            {
                                order.invoiceStatus = 2;
                                orderHc.invoiceStatus = 2;
                                SqlSugarFactory.Instance.Updateable(order).ExecuteCommand();
                                SqlSugarFactory.Instance.Updateable(orderHc).ExecuteCommand();
                            }
                        }
                        return (Result.success("取消成功！"));
                    }
                    else
                    {
                        _logger.LogInformation($"退款单号[{orders_id}]->患者姓名{patient.name},退款失败");

                        return (Result.fail("退款失败！"));
                    }
                }
                else
                {
                    return (Result.fail("查询订单失败！"));
                }

                //var order =new 

            }
            else if (book.status == "2" || (book.status == "5" && book.medicare == 1))
            {
                _logger.LogInformation($"退款单号[{orders_id}]->患者姓名{patient.name},医保卡支付请到现场退费");
                //医保卡的现场退费
                return (Result.fail("医保卡支付请到现场退费！"));

            }
            else
            {
                //其他情况不能退款
                _logger.LogInformation($"退款单号[{orders_id}]->患者姓名{patient.name},您的订单不支持退款");

                return (Result.fail("您的订单不支持退款！"));
            }
        }
        /// <summary>
        /// 预约
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("Create")]
        public Result Create(BookCreateInput input)
        {
            //Core.Utils.QRCodeHelper he = new Core.Utils.QRCodeHelper();
            //var bit = he.CreateQRimg(orderno);
            //var root = _iHostEnvironment.WebRootPath;
            //var savaPath = "\\book\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\" + orderno + ".jpg";
            //if (!Directory.Exists(Path.GetDirectoryName(root + savaPath)))
            //{
            //    Directory.CreateDirectory(Path.GetDirectoryName(root + savaPath));
            //}
            //bit.Save(root + savaPath);

            var queryBook = SqlSugarFactory.Instance.Queryable<book_info>()
                .First(i => i.pat_id == input.pat_id && i.appo_date.Date == input.appo_date.Date 
                && i.range_id == input.range_id);
            if (queryBook != null)
            {
                return Result.fail("您已预约了当前时间,无需重复预约!");
            }
            //判断预约日期是不是小于当前日期
            if (input.appo_date.Date < DateTime.Now.Date)
            {
                return Result.fail("不能预约当前日期以前的日期!");

            }
            var range = SqlSugarFactory.Instance.Queryable<time_range>()
                .First(i => i.range_id == input.range_id);

            //查询这个时段预约的人数
            var randids = SqlSugarFactory.Instance.Queryable<time_range>()
             .Where(it => it.range == range.range && it.status == "0").Select(it => it.range_id).ToList();
            var count = SqlSugarFactory.Instance.Queryable<book_info>().Where(i =>
            randids.Contains(i.range_id) && i.appo_date.Date == input.appo_date.Date && i.status != "4" && i.status != "5").Count();

            //
            var timeRangeMax = SqlSugarFactory.Instance.Ado.SqlQuery<time_range>("select distinct range,max_num from time_range(nolock)")
                .Sum(x=>x.max_num);
            if (count>=timeRangeMax)
            {
                return Result.fail("当前时段已经约满,请选择其他时段!!");
            }

            //当天预约的预约时间,是不是小于当前的截至时间
            if (input.appo_date.Date == DateTime.Now.Date && range != null)
            {
                var rangeArr = range.range.Split(new char[] { '-' });
                if (rangeArr.Length == 2)
                {
                    DateTime dt1 = Convert.ToDateTime(rangeArr[1]);
                    DateTime dt2 = Convert.ToDateTime(DateTime.Now.ToString("HH:mm"));

                    if (DateTime.Compare(dt2, dt1) >= 0)
                    {
                        return Result.fail("当天预约:只能预约截止时间以后的时段!");
                    }
                }
            }
            var orderno = UniqueData.Gener("");

            book_info book = new book_info
            {
                pat_id = input.pat_id,
                appo_date = input.appo_date,
                range_id = input.range_id,
                item_id = input.item_id,
                inves_id = input.inves_id,
                ins_time = DateTime.Now,
                orders_id = orderno,
                status = "0",
                update_time = DateTime.Now,
                type_id = input.type_id,
            };
            var app_id = SqlSugarFactory.Instance.Insertable(book).ExecuteReturnIdentity();
            return Result.success(orderno);
        }
        /// <summary>
        /// 查询时段内已经预约的人数
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("QueryCount")]
        public Result QueryCount(BookQueryCountInput input)
        {
            var randids = SqlSugarFactory.Instance.Queryable<time_range>()
               .Where(it => it.range == input.range && it.status == "0").Select(it => it.range_id).ToList();
            var count = SqlSugarFactory.Instance.Queryable<book_info>().Where(i =>
            randids.Contains(i.range_id) && i.appo_date.Date == input.appo_date.Date&&i.status!="4"&&i.status!="5").Count();
            return Result.success(count);
        }
        /// <summary>
        /// 查询预约信息
        /// </summary>
        /// <param name="idnum"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("Query")]
        public Result<PagedResultDto<BookInfoQueryDto>> Query(BookInfoQueryInput input)
        {
           
            var patient = SqlSugarFactory.Instance.Queryable<patient_info>().First(i => i.idnum == input.idnum);
            if (patient == null)
            {
                return Result<PagedResultDto<BookInfoQueryDto>>.fail("信息未找到");
            }
            var totalCount = 0;
            var root = _iHostEnvironment.WebRootPath;

            var items = SqlSugarFactory.Instance.Queryable<book_info>()
                .InnerJoin<patient_info>((t1, t2) => t1.pat_id == t2.pat_id)
                .InnerJoin<time_range>((t1, t2, t3) => t1.range_id == t3.range_id)
                .InnerJoin<check_item>((t1, t2, t3, t4) => t1.item_id == t4.item_id)
                .InnerJoin<check_type>((t1, t2, t3, t4, t5) => t4.item_id == t5.item_id)
                .WhereIF(input.status != null && input.status.Count > 0, (t1, t2, t3, t4, t5) => input.status.Contains(t1.status))
                .WhereIF(input.medicare.HasValue, (t1, t2, t3, t4, t5) => input.medicare == (t1.medicare))

                .Where((t1, t2, t3, t4, t5) => t1.pat_id == patient.pat_id).OrderBy((t1, t2, t3, t4, t5) => t1.ins_time, SqlSugar.OrderByType.Desc)
                .Select((t1, t2, t3, t4, t5) => new BookInfoQueryDto
                {
                    appo_id = t1.appo_id,
                    patient_name = t2.name,
                    sex = t2.sex,
                    idnum = t2.idnum,
                    appo_date = t1.appo_date,
                    range = t3.range,
                    status = t1.status,
                    item_name = t4.name,
                    price = t4.price,
                    type_name = t5.name,
                    ins_time = t1.ins_time,
                    orders_id = t1.orders_id,
                    medicare = t1.medicare
                }).ToPageList(input.pageIndex, input.pageSize, ref totalCount);
            var result = new PagedResultDto<BookInfoQueryDto>(
           totalCount, items.Select(item =>
           {
               var dto = new BookInfoQueryDto();
               dto.patient_name = item.patient_name;
               dto.sex = item.sex;
               dto.idnum = item.idnum;
               dto.appo_date = item.appo_date;
               dto.range = item.range;
               dto.status = item.status;
               dto.item_name = item.item_name;
               dto.price = item.price;
               dto.type_name = item.type_name;
               dto.ins_time = item.ins_time;
               dto.orders_id = item.orders_id;
               dto.medicare = item.medicare;
               dto.qrcode = Core.Utils.QRCodeHelper.BitmapConvertToString(Core.Utils.QRCodeHelper.GenerateQRCode(item.orders_id));
               //var savaPath = "\\book\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\" + item.orders_id + ".jpg";

               //if (!System.IO.File.Exists(root+ savaPath))
               //{
               //    if (!Directory.Exists(Path.GetDirectoryName(root + savaPath)))
               //    {
               //        Directory.CreateDirectory(Path.GetDirectoryName(root + savaPath));
               //    }
               //    Core.Utils.QRCodeHelper he = new Core.Utils.QRCodeHelper();
               //    var bit = he.CreateQRimg(dto.orders_id);
               //    bit.Save(root + savaPath);
               //}
               //dto.qrcode = savaPath.Replace("\\","/");
               return dto;
           }).ToList());
            return Result<PagedResultDto<BookInfoQueryDto>>.success(result); ;
        }

        [HttpPost]
        [Route("QueryByOrder")]
        public Result<BookInfoQueryDto> QueryByOrder(string orders_id)
        {
           

            var book = SqlSugarFactory.Instance.Queryable<book_info>().First(x => x.orders_id == orders_id);
            if (book==null)
            {
                return Result<BookInfoQueryDto>.fail("未找到订单");
            }
            var patient = SqlSugarFactory.Instance.Queryable<patient_info>().First(i => i.pat_id == book.pat_id);
            if (patient == null)
            {
                return Result<BookInfoQueryDto>.fail("患者信息未找到");
            }

            if (book.status=="0")
            {
                //刷新支付状态
                JHRefundApp jhRefundApp = new JHRefundApp();
                xmlToolApp XMLToolApp = new xmlToolApp();
                //查询建行本订单金额
                string returnStr = jhRefundApp.GetOrder(orders_id);
                //建行订单状态 成功000000
                var code = XMLToolApp.GetTextBydoc(returnStr, "RETURN_CODE");

                if (code == "000000")
                {
                    var sate = XMLToolApp.GetTextBydoc(returnStr, "ORDER_STATUS");
                    //0:失败,1:成功,2:待银行确认,3:已部分退款,4:已全额退款,5:待银行确认
                    var dt = DateTime.Now;

                    if (sate == "1")
                    {
                        var TRAN_DATE = XMLToolApp.GetTextBydoc(returnStr, "TRAN_DATE");
                        //
                        book.status = "1";
                        book.update_time = dt;
                        SqlSugarFactory.Instance.Updateable(book).ExecuteCommand();

                        var item = SqlSugarFactory.Instance.Queryable<check_item>().First(i => i.item_id == book.item_id);
                        var itemtype = SqlSugarFactory.Instance.Queryable<check_type>().First(i => i.item_id == book.item_id);

                        order_info order_ = SqlSugarFactory.Instance.Queryable<order_info>().First(i => i.orders_id == book.orders_id);
                        if (order_ == null)
                        {
                            order_ = new order_info
                            {
                                pay_time = Convert.ToDateTime(TRAN_DATE),
                                pat_id = book.pat_id,
                                appo_id = book.appo_id,
                                item_id = book.item_id,
                                price = item.price,
                                num = itemtype.num,
                                orders_id = book.orders_id,
                                wx_order_no = "建行",
                                status = "0",
                                invoiceStatus = 0
                            };
                            if (patient != null)
                            {
                                order_.tel = patient.tel;
                                order_.idnum = patient.idnum;
                                order_.pat_name = patient.name;
                            }
                            SqlSugarFactory.Instance.Insertable<order_info>(order_).ExecuteCommand();
                            _logger.LogInformation($"[{orders_id}]->[刷新银行状态]->写入数据库");
                        }


                        //发票处理------------------------
                        //查询开票状态
                        var invStatus = hebczUtil.invoicestatus(orders_id);
                        _logger.LogInformation($"[{orders_id}]->[刷新银行状态]->查询发票状态:" + JsonConvert.SerializeObject(invStatus));
                        if (invStatus.code < 1 || invStatus.data.Count == 0 || invStatus.data[0].state == "0")
                        {
                            _logger.LogInformation($"[{orders_id}]->[刷新银行状态]->申请发票");
                            mkomedicaleinvoiceModel model = new mkomedicaleinvoiceModel()
                            {
                                einvoicespecimen = "1",
                                issuedate = dt.ToString("yyyyMMdd"),
                                issuetime = dt.ToString("hh:mm:ss"),
                                payerpartytype = "1",
                                payerpartyname = patient.name,
                                totalamount = double.Parse(item.price.ToString()).ToString(),
                                bizcode = orders_id,
                                handlingperson = hebczConst.handlingperson,
                                checker = hebczConst.checker,
                                fundpayamount = "0",
                                otherpayamount = "0",
                                accountpayamount = "0",
                                ownpayamount = double.Parse(item.price.ToString()).ToString(),
                                //relatedinvoicecode = "1253",
                                //relatedinvoicenumber = orders_id,
                            };
                            model.details.Add(new details
                            {
                                itemcode = hebczConst.item_code,
                                itemname = hebczConst.item_name,
                                itemamount = double.Parse(item.price.ToString()).ToString(),

                            });
                            model.auxdetails.Add(new auxdetails
                            {
                                auxitemrelatedcode = hebczConst.item_code,
                                auxitemrelatedname = hebczConst.item_name,
                                auxitemname = item.name,
                                auxitemamount = double.Parse(item.price.ToString()).ToString()
                            });
                            HttpHelperMin http = new HttpHelperMin();
                            HttpItemMin httpitem = new HttpItemMin()
                            {
                                URL = hebczConst.Url + "/mkomedicaleinvoice",
                                Method = "POST",
                                ContentType = "application/json",
                                Postdata = JsonConvert.SerializeObject(model),
                            };
                            var resule = http.GetHtml(httpitem);
                            _logger.LogInformation($"[{orders_id}]->[刷新银行状态]->申请发票返回:" + resule.Html);
                            invStatus = JsonConvert.DeserializeObject<ReturnData<MeInvoiceStatusDto>>(resule.Html);

                            if (invStatus != null && invStatus.code == 1)
                            {
                                //查询开票状态
                                invStatus = hebczUtil.invoicestatus(orders_id);
                                _logger.LogInformation($"[{orders_id}]->[刷新银行状态]->查询发票状态:" + JsonConvert.SerializeObject(invStatus));
                                //如果没有获取过，申请电子发票
                                if (invStatus != null && invStatus.code == 1 && invStatus.data.Count > 0 && invStatus.data[0].state != "0")
                                {
                                    order_.einvoicecode = invStatus.data[0].einvoicecode;
                                    order_.einvoicenumber = invStatus.data[0].einvoicenumber;
                                    order_.randomnumber = invStatus.data[0].randomnumber;
                                    order_.invoiceStatus = 1;
                                    SqlSugarFactory.Instance.Updateable(order_).ExecuteCommand();
                                }

                            }
                        }
                        else
                        {
                            order_.einvoicecode = invStatus.data[0].einvoicecode;
                            order_.einvoicenumber = invStatus.data[0].einvoicenumber;
                            order_.randomnumber = invStatus.data[0].randomnumber;
                            order_.invoiceStatus = 1;
                            SqlSugarFactory.Instance.Updateable(order_).ExecuteCommand();
                        }

                    }
                }
            }
            
            var ran= SqlSugarFactory.Instance.Queryable<time_range>().First(i => i.range_id == book.range_id);
            var check_Item = SqlSugarFactory.Instance.Queryable<check_item>().First(i => i.item_id == book.item_id);
            var check_type = SqlSugarFactory.Instance.Queryable<check_type>().First(i => i.item_id == check_Item.item_id);

            var dto = new BookInfoQueryDto();
            dto.patient_name = patient.name;
            dto.sex = patient.sex;
            dto.idnum = patient.idnum;
            dto.appo_date = book.appo_date;
            dto.range = ran.range;
            dto.status = book.status;
            dto.item_name = check_Item.name;
            dto.price = check_Item.price;
            dto.type_name = check_type.name;
            dto.ins_time = book.ins_time;
            dto.orders_id = book.orders_id;
            dto.medicare = book.medicare;
            dto.qrcode = Core.Utils.QRCodeHelper.BitmapConvertToString(Core.Utils.QRCodeHelper.GenerateQRCode(book.orders_id));
            return Result<BookInfoQueryDto>.success(dto) ;
        }
    }
}
